#include<stdio.h>
#include<stdlib.h>
#define WSIZE   4
#define DSIZE   8
#define MAX(x,y) ((x) > (y)?(x) :(y))

/* Pack a size and allocated bit into a word */
#define PACK(size, alloc) ((size) | (alloc))

/* Read and write a word at address p */
#define GET(p)          (*(size_t *)(p))
#define PUT(p,val)      (*(size_t *)(p) = ((size_t)val))

/* Read the size and allocated fields from address p */
#define GET_SIZE(p)     (GET(p) & ~0x7)
#define GET_ALLOC(p)    (GET(p) & 0x1)

/* Given block ptr bp, compute address of its header and footer */
#define A_HDRP(bp)        ((char *)(bp) - WSIZE)
#define A_FTRP(bp)        ((char *)(bp) + GET_SIZE(A_HDRP(bp)) - DSIZE)

/* Given an allocated block ptr bp, compute address of next and previous blocks */
#define A_NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
#define A_PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))

/* Given a free block ptr bp, return the address of the next and prev pointers */
#define F_NP(bp) ((char *)(bp) + DSIZE)
#define F_PP(bp) ((char *)(bp) + WSIZE)

/* Given a free block ptr bp, compute address of next and previous blocks */
#define F_NEXT_BLKP(bp) ((char*)*(size_t*)(F_NP(bp)))
#define F_PREV_BLKP(bp) ((char*)*(size_t*)(F_PP(bp)))

/* Given a free block ptr bp, return whether it has a next / prev */
#define F_HAS_NEXT(bp) ((size_t*)F_NEXT_BLKP(bp)!=NULL)
#define F_HAS_PREV(bp) ((size_t*)F_PREV_BLKP(bp)!=NULL)

/* Given a header pointer of a free block, return the address of its header */
#define F_FTRP(bp) ((char *)(bp) + GET_SIZE(bp) - WSIZE)

/* Convert to and from free_style bp and allocated_style bps */
#define F_TO_A(bp) ((char *)(bp) + WSIZE)
#define A_TO_F(bp) ((char *)(bp) - WSIZE)

typedef struct {
int a;
int b;
int c;
int d;
} free_block;

free_block b1, b2, b3,b4, b5; 
//free style pointers
char* b1f = &b1;
char* b2f = &b2;
char* b3f = &b3;
char* b4f = &b4;
char* b5f = &b5;

//allocated style pointers
char* b1a = (char*)&b1+4;
char* b2a = (char*)&b2+4;
char* b3a = (char*)&b3+4;
char* b4a = (char*)&b4+4;
char* b5a = (char*)&b1+4;

void* x;

void init(){
x = b1a;

    PUT(A_HDRP(b1a),PACK(16,0));
    PUT(F_NP(b1f),b2f);
    PUT(F_PP(b1f),NULL);
    PUT(A_HDRP(b1a),PACK(16,0));

    PUT(A_HDRP(b2a),PACK(16,0));
    PUT(F_NP(b2f),NULL);
    PUT(F_PP(b2f),b1f);
    PUT(A_HDRP(b2a),PACK(16,0));
}

main()
{
    init();

    printf("%u\n",b1f);
    printf("%u\n",b1a);
    printf("%u\n",F_NEXT_BLKP(b1f));
    printf("%u\n",b2f); //these two lines should be equal
    printf("%u\n",b2a);
    printf("%u\n",(size_t)NULL);

    printf("%u %u\n",b1a,b1a+4);
}
